<?php

namespace app\common\model;

use MongoDB\BSON\ObjectId;
use app\common\lib\ZhyxMongo;
use catcher\exceptions\FailedException;
use app\common\model\search\FollowSearch;
use app\common\model\PatientInfo as PatientInfoModel;
use app\common\model\FollowHistory as FHModel;
use catchAdmin\permissions\model\Users as UsersModel;
use MongoDB\BSON\UtcDateTime;
use app\common\model\Followtask as FollowtaskModel;

class Follow extends BaseModel
{
    use FollowSearch;

    protected $name = "follow";

    protected $field=[
        'follow_id' => "objectId",
        'task_id' => "objectId"
    ];
    /**
     * 方式
     */
    public function getModeAttr($value)
    {
        $list = [
            1  => "微信",
            2  => "短信",
            3  => "APP/短信",
            4  => "电话"
        ];
        return !empty($list[$value])?$list[$value]:"";
    }

    /**
     * 随访状态
     */
    public function getFollowStatusAttr($value)
    {
        $list = [
            0 => "未完成",
            1 => "已完成",
            2 => "暂存"
        ];
        return !empty($list[$value])?$list[$value]:"未完成";
    }

    /**
     * 获取数据列表
     * @param int $type 1分页数据 2列表数据
     * @param string $field 字段
     */
    public function getLists(int $type=1, string $field ="*")
    {
	    #$user = request()->user();
        #$req = request()->param();

        $historyModel = (new FHModel());
        $patientModel = (new PatientInfoModel());

        #$roles = (new UsersModel())->currentUserRoleInfo($user['id'], 'role.identify')->column('identify');

        $where = [];
//        if (!empty(array_intersect($roles, ['dsjzxsfry']))) {
//            $where[] = ['follow_staff.user_id', '=', $user['id']];
//        }
//
////        $condition = [];
////        if (isset($req["bz"]) && !empty($req["bz"])) {
////            $condition[] = ['$in' => ['$$item.bingzhong_id', $req["bz"]]];
////        }
        //halt($condition);
        if ($type == 1) {
            return $this->mongoSearch([],[],['type'])
                ->where($where)
                ->field(['id','pid','task_id','task_name', 'patientId', 'sex', 'name', 'presentTelphone', 'diagnosis', 'status', 'followStatus','pushdatetime', 'pushtime', 'mode', 'audio', 'outhospitalDate', 'time_of_birth', 'medicalRecordsNo', 'create_date', 'inchargeDoctorName', 'inhospitalNo', 'outhospitalDept'])
                ->order('_id', 'desc')
                ->paginate($this->pageLimit)
                ->each(function ($item, $key) use($patientModel, $historyModel) {
                    $patientInfo = (new PatientInfoModel())->where('id', $item['pid'])->field('staging_status')->find();
                    $item['attendingDoctorName'] = $item['inchargeDoctorName'];
                    $item["pushdatetime"] = isset($item['pushdatetime'])&&!empty($item['pushdatetime'])?$item['pushdatetime']:"";
                    if (isset($phone['audio'])) {
                        $item['audio'] = request()->domain() . request()->server('port') . $phone['audio'];
                    }else{
                        $item['audio'] = '';
                    }
                    $item['staging_status'] = $patientInfo['staging_status']??'';
                    $item['isStaging'] = $item['staging_status'] == 1?'是':'';
                    return $item;
                });
        }else{
            return $this->mongoSearch()
                ->where($where)
                ->field(['id','pid','task_id','task_name', 'patientId', 'sex', 'name', 'presentTelphone', 'diagnosis', 'status', 'followStatus', 'resultName', 'result', 'pushdatetime', 'pushtime', 'mode', 'audio','bz', 'wechatStatus','smsStatus'])
                ->order('_id', 'desc')
                ->select()
                ->each(function ($item, $key) use($patientModel, $historyModel) {
                    $patient = $patientModel->getOneData(['id' => $item['pid']], 'medicalRecordsNo,outList');
                    $phone = $historyModel->getOneData(['follow_id' => new ObjectId($item['id']), 'mode' => 4]);
                    $item['medicalRecordsNo'] = $patient['medicalRecordsNo']??'';
                    $item['clinicNo'] = $patient['outList']['clinicNo']??'';
                    $item['attendingDoctorName'] = $patient['outList']['attendingDoctorName']??'';
                    $item['wechatStatus'] = isset($item['wechatStatus'])&&$item['wechatStatus'] == 1?'已发送':'';//微信状态
                    $item['smsStatus'] = isset($item['smsStatus'])&&$item['smsStatus'] == 1?'已发送':'';//短信状态
                    $item['result'] = $item['resultName']??'';//电话随访结果
                    $item['result_id'] = $item['result']??'';//电话随访结果id
                    $item["pushdatetime"] = isset($item['pushdatetime'])&&!empty($item['pushdatetime'])?$item['pushdatetime']:"";
                    unset($item['pid']);
                    return $item;
                });
        }

    }

    /**
     * 收案随访获取数据列表
     * @param int $type 1分页数据 2列表数据
     * @param string $field 字段
     */
    public function getLists2(int $type=1, string $field ="*")
    {
        $user = request()->user();
        $req = request()->param();

        $historyModel = (new FHModel());
        $patientModel = (new PatientInfoModel());

        $roles = (new UsersModel())->currentUserRoleInfo($user['id'], 'role.identify')->column('identify');

        $where = [];
        if (!empty(array_intersect($roles, ['dsjzxsfry']))) {
            $where[] = ['follow_staff.user_id', '=', $user['id']];
        }

        $condition = [];
        if (isset($req["bz"]) && !empty($req["bz"])) {
            $condition[] = ['$in' => ['$$item.bingzhong_id', $req["bz"]]];
        }
        //halt($condition);
        if ($type == 1) {
            return $this->mongoSearch([],[],['type'])
                ->where($where)
                ->field(['id','pid','task_id','task_name', 'patientId', 'sex', 'name', 'presentTelphone', 'diagnosis', 'status', 'followStatus', 'resultName', 'result', 'pushdatetime', 'pushtime', 'mode', 'audio','bz', 'wechatStatus','smsStatus','bzItem' => [
                    '$filter' => [
                        'input' => '$bz.bingzhongArr',
                        'as' => 'item',
                        'cond' => [
                            '$and' => [
                                $condition
                            ]
                        ]
                    ]
                ]])
                ->order('_id', 'desc')
                ->paginate($this->pageLimit)
                ->each(function ($item, $key) use($patientModel, $historyModel) {
                    $patient = $patientModel->getOneData(['id' => $item['pid']], 'medicalRecordsNo,outList,is_in_hospital,presentTelphone');
                    $phone = $historyModel->getOneData(['follow_id' => new ObjectId($item['id']), 'mode' => 4]);
                    $item['medicalRecordsNo'] = $patient['medicalRecordsNo']??'';
                    $item['clinicNo'] = $patient['outList']['clinicNo']??'';
                    $item['attendingDoctorName'] = $patient['outList']['attendingDoctorName']??'';
                    $item['diagnosis'] = $patient['outList']['diseaseList'][0]['diseaseName']??'';
                    $item['presentTelphone'] = $patient['presentTelphone']??'';
                    $item['wechatStatus'] = isset($item['wechatStatus'])&&$item['wechatStatus'] == 1?'已发送':'';//微信状态
                    $item['smsStatus'] = isset($item['smsStatus'])&&$item['smsStatus'] == 1?'已发送':'';//短信状态
                    $item['result'] = $item['resultName']??'';//电话随访结果
                    $item['result_id'] = $item['result']??'';//电话随访结果id
                    $item["pushdatetime"] = isset($item['pushdatetime'])&&!empty($item['pushdatetime'])?$item['pushdatetime']:"";
                    if (isset($phone['audio'])) {
                        $item['audio'] = request()->domain() . request()->server('port') . $phone['audio'];
                    }else{
                        $item['audio'] = '';
                    }
                    $item['is_in_hospital'] = $patient['is_in_hospital']==1?'是':'否';
                    return $item;
                });
        }else{
            return $this->mongoSearch()
                ->where($where)
                ->field(['id','pid','task_id','task_name', 'patientId', 'sex', 'name', 'presentTelphone', 'diagnosis', 'status', 'followStatus', 'resultName', 'result', 'pushdatetime', 'pushtime', 'mode', 'audio','bz', 'wechatStatus','smsStatus','bzItem' => [
                    '$filter' => [
                        'input' => '$bz.bingzhongArr',
                        'as' => 'item',
                        'cond' => [
                            '$and' => [
                                $condition
                            ]
                        ]
                    ]
                ]])
                ->order('_id', 'desc')
                ->select()
                ->each(function ($item, $key) use($patientModel, $historyModel) {
                    $patient = $patientModel->getOneData(['id' => $item['pid']], 'medicalRecordsNo,outList.clinicNo,inList.inchargeDoctorName');
                    $phone = $historyModel->getOneData(['follow_id' => new ObjectId($item['id']), 'mode' => 4]);
                    $item['medicalRecordsNo'] = $patient['medicalRecordsNo']??'';
                    $item['clinicNo'] = $patient['outList']['clinicNo']??'';
                    $item['attendingDoctorName'] = $patient['inList']['inchargeDoctorName']??'';
                    $item['wechatStatus'] = isset($item['wechatStatus'])&&$item['wechatStatus'] == 1?'已发送':'';//微信状态
                    $item['smsStatus'] = isset($item['smsStatus'])&&$item['smsStatus'] == 1?'已发送':'';//短信状态
                    $item['result'] = $item['resultName']??'';//电话随访结果
                    $item['result_id'] = $item['result']??'';//电话随访结果id
                    $item["pushdatetime"] = isset($item['pushdatetime'])&&!empty($item['pushdatetime'])?$item['pushdatetime']:"";
                    unset($item['pid']);
                    return $item;
                });
        }

    }

    /**
     * 添加数据
     * @param array $param
     * @return string
     */
    public function addData(array $param): string
    {
        //添加时销毁自带的主键id
        unset($param['id']);
        return $this->save($param);
    }

    /**
     * 更新数据
     * @param array $param
     * @return bool
     */
    public function saveData($id, array $param): bool
    {
        $model = self::find($id);
        return $model->save($param);
    }

    /**
     * 删除
     * @return bool
     */
    public function del(array $id): bool
    {
        return self::destroy($id);
    }

    /**
     * 获取患者随访记录
     * @param string $id 患者主键
     * @param string $history_id 随访记录主键
     */
    public function getRecord(string $id = '', string $history_id = '')
    {
        $where = [];
        if (!empty($history_id)) {
            $where[] = ['id', '=', $history_id];
        }
        $where[] = ['pid', '=', $id];


        return  (new FHModel())
                    ->mongoSearch([],[],['id','history_id'])
                    ->field('id,mode,task_id,follow_id,projectId,projectName,answer_id,staffName,staffDoctorCode,pushtime,status,taskname,patientId')
                    ->where($where)
                    ->order('_id', 'desc')
                    ->select()
                    ->each(function ($item, $key) {
                        $item['follow_staff'] = $item['staffName'].'('.$item['staffDoctorCode'].')';
                        if (!isset($item['staffDoctorCode'])) {
                            $item['follow_staff'] = '自动随访';
                        }

                        //返回随访计划状态 标记结束字段
                        $task = (new FollowtaskModel())->where('id', $item['task_id'])->field('status')->find();
                        if (!empty($task['status'])) {
                            $item['isEnd'] = true;
                        }
                    });
    }

    /**
     * 获取患者端随访表单
     * @param string $patientId 患者id
     * @param int $type 0 未完成，1已完成
     * @return \think\Paginator
     */
    public function getPatientFollow(string $patientId, int $type = 0): \think\Paginator
    {
        $where = [];
        $where[] = ['patientId', '=', $patientId];
        $where[] = ['mode', 'in', array(1,2,3)];
        if ($type == 1) {
            $where[] = ['status', '=', 2];
        } else {
            $where[] = ['status', '<>', 2];
        }
        return (new FHModel())->where($where)
            ->field('id,patientId,staffName,staffDepartmentName,staffId,projectId,projectName,status,answer_id,follow_id')
            ->order('pushdatetime', 'desc')
            ->paginate($this->pageLimit)
            ->each(function ($item, $key) {
                if (empty($item['follow_id'])) {
                    $item['follow_staff'] = '自动随访';
                }else{
                    $item['follow_staff'] = $item['staffName'];
                }
                $item['department']   = $item['staffDepartmentName'];
                $item['pushStaff']    = $item['staffId'];
                return $item;
            });
    }

    /**
     * 随访人员获取随访患者
     */
    public function getStaffFollow($follow_staff)
    {
        //总随访
        $totalWhere['follow_staff'] = $follow_staff;
        $data['total'] = $this->where($totalWhere)->whereNotNull('pushtime')->count();

        //已随访
        $ysfWhere['status'] = 2;
        $ysfWhere['follow_staff'] = $follow_staff;
        $data['ysf'] = $this->where($ysfWhere)->count();

        //待随访
        $dsfWhere['status'] = ['<>', 2];
        $dsfWhere['follow_staff'] = $follow_staff;
        $data['dsf'] = $this->where($dsfWhere)->whereNotNull('pushtime')->count();

        //今日随访
        $todayWhere['pushtime'] = date("Y-m-d");
        $todayWhere['follow_staff'] = $follow_staff;
        $data['today'] = $this->where($todayWhere)->count();

        return $data;
    }

    /**
     * 工作台任务中心
     */
    public function getGztList($id)
    {
        return $this->where('follow_staff', $id)
            ->order('created_at', 'desc')
            ->limit(5)
            ->select()
            ->each(function ($item, $key) {
                $patient = (new PatientInfoModel)
                    ->where('id', $item['pid'])
                    ->field('medicalRecordsNo,outList')
                    ->find()
                    ->toArray();

                $item['medicalRecordsNo'] = $patient['medicalRecordsNo'];
                $item['clinicNo'] = isset($patient['outList']['clinicNo']) ? $patient['outList']['clinicNo'] : '';
                $item['diagnosis'] = isset($patient['outList']['diagnosis']) ? $patient['outList']['diagnosis'] : '';
                $item['attendingDoctorName'] = isset($patient['outList']['attendingDoctorName']) ? $patient['outList']['attendingDoctorName'] : '';
                return $item;
            })
            ->toArray();
    }

    /**
     * 条件获取数据
     * @param array $where 查询条件
     * @param string $field 字段
     */
    public function getOneData(array $where=[], string $field="*", $sort="desc")
    {
        return  $this->where($where)->field($field)->order('created_at', $sort)->find();
    }

    /**
     * 获取条件匹配的数据
     * @param array $where 条件
     * @param string $field 字段
     * @return array
     */
    public function getConditionData(array $where=[], string $field="*"): array
    {
        return  $this->field($field)->where($where)->select()->toArray();
    }

    /**
     * 获取条件匹配的统计数
     * @param array $where 条件
     * @return int
     */
    public function getConditionCount(array $where=[]): int
    {
        return  $this->where($where)->count();
    }

    /**
     * mongo追加新元素到array类型字段
     * @param string $id 主键
     * @param string $field 字段
     * @param array $data 参数
     * @return bool
     */
    public function appToData(string $id, string $field, array $data=[]): bool
    {
        try {
            ZhyxMongo::getInstance()->setCollection($this->name)->updateMany(["_id" => new ObjectId($id)], ['$push' => [$field => ['$each' => $data]]]);
            return  true;
        } catch (\Exception $exception) {
            throw new FailedException($exception->getMessage());
        }
    }

    /**
     * 统计部门报表
     *
     * @return array
     */
    public function getFollowDepartmentList(): array
    {
        $req = request()->param();

        $where = [];
        if (isset($req['task_id']) && !empty($req['task_id'])) {
            $where[] = ['id', '=', new ObjectId($req['task_id'])];
        }

        if (isset($req['status']) && !empty($req['status'])) {
            $where[] = ['status', '=', (int)$req['status']];
        }

        if (isset($req['created_ymd']) && !empty($req['created_ymd'])) {
            $start_time = new UtcDateTime(strtotime($req['created_ymd'][0])*1000);
            $end_time   = new UtcDateTime(strtotime($req['created_ymd'][1].' 23:59:59')*1000);
            $where[] = ['created_ymd', '>=', $start_time];
            $where[] = ['created_ymd', '<=', $end_time];
        }

        $task_id = (new FollowtaskModel())->getKvData($where);

        $match = [];
        if (!empty($task_id)) {
            $task_ids = array_map(function ($v) { return new ObjectId($v); }, $task_id);
            $match["task_id"] = ['$in' => $task_ids];
        }

        if (isset($req['department_Id']) && !empty($req['department_Id'])) {
            $match['dept_id'] = $req['department_Id'];
        }

        if (empty($match)) {
            return [];
        }

        $pip = [['$match' => $match], ['$group' => ['_id' => ['$sum' => '$dept_id'], 'department_name' => ['$first' => '$department_name'], 'task_num' => ['$sum' => '$task_num'], 'task_completed_number' => ['$sum' => '$task_completed_number'], 'phone_completed' => ['$sum' => '$phone_completed'], 'sms_completed' => ['$sum' => '$sms_completed'], 'phone_total' => ['$sum' => '$phone_total'], 'sms_total' => ['$sum' => '$sms_total'], 'duration' => ['$sum' => '$duration'], 'phone_ff_number' => ['$sum' => '$phone_ff_number'], 'phone_gj_number' => ['$sum' => '$phone_gj_number'], 'phone_hmcw_number' => ['$sum' => '$phone_hmcw_number'], 'phone_hmwx_number' => ['$sum' => '$phone_hmwx_number'], 'phone_jjsf_number' => ['$sum' => '$phone_jjsf_number'], 'phone_jsjt_number' => ['$sum' => '$phone_jsjt_number'], 'phone_kh_number' => ['$sum' => '$phone_kh_number'], 'phone_mzsc_number' => ['$sum' => '$phone_mzsc_number'], 'phone_qtqk_number' => ['$sum' => '$phone_qtqk_number'], 'phone_sw_number' => ['$sum' => '$phone_sw_number'], 'phone_tj_number' => ['$sum' => '$phone_tj_number'], 'phone_wd_number' => ['$sum' => '$phone_wd_number'], 'phone_wfjt_number' => ['$sum' => '$phone_wfjt_number'], 'phone_wrjt_number' => ['$sum' => '$phone_wrjt_number'], 'phone_zdjj_number' => ['$sum' => '$phone_zdjj_number'], 'phone_zy_number' => ['$sum' => '$phone_zy_number'], 'phone_zysc_number' => ['$sum' => '$phone_zysc_number']]], ['$project' => ['_id' => false, 'dept_id' => '$_id', 'department_name' => '$department_name', 'task_num' => '$task_num', 'task_completed_number' => '$task_completed_number', 'phone_completed' => '$phone_completed', 'sms_completed' => '$sms_completed', 'phone_total' => '$phone_total', 'sms_total' => '$sms_total', 'duration' => '$duration', 'patient_result' => ['phone_ff_number' => '$phone_ff_number', 'phone_mzsc_number' => '$phone_mzsc_number', 'phone_qtqk_number' => '$phone_qtqk_number', 'phone_sw_number' => '$phone_sw_number', 'phone_wd_number' => '$phone_wd_number', 'phone_zy_number' => '$phone_zy_number', 'phone_zysc_number' => '$phone_zysc_number'], 'phone_result' => ['phone_gj_number' => '$phone_gj_number', 'phone_hmcw_number' => '$phone_hmcw_number', 'phone_hmwx_number' => '$phone_hmwx_number', 'phone_jjsf_number' => '$phone_jjsf_number', 'phone_jsjt_number' => '$phone_jsjt_number', 'phone_kh_number' => '$phone_kh_number', 'phone_tj_number' => '$phone_tj_number', 'phone_wfjt_number' => '$phone_wfjt_number', 'phone_zdjj_number' => '$phone_zdjj_number', 'phone_wrjt_number' => '$phone_wrjt_number']]]];
        
        $rets = ZhyxMongo::getInstance()->setCollection("follow_report")->aggregate($pip);
       
        $arr = [];
        foreach ($rets as $k => $v) {
            $arr[] = $v;
        }
        return $arr;
    }

    /**
     * 统计部门报表详情
     *
     * @param array $condition 查询条件
     * @return array
     */
    public function getFollowDepartmentDetailedList(array $condition=[]): array
    {
        $match = [];
        if (isset($condition["created_ymd"]) && !empty($condition["created_ymd"])){
            $start_time = new UtcDateTime(strtotime($condition['created_ymd'][0])*1000);
            $end_time   = new UtcDateTime(strtotime($condition['created_ymd'][1].' 23:59:59')*1000);
            $match["created_at"] = ['$gte' => $start_time,'$lte' => $end_time]; //拼接查询日期
        }

        $paramArr = ["dept_id" => "department_id", "task_id" => "task_id", "status" => "status"];
  
        foreach($paramArr as $k => $v){
            if(isset($condition[$k]) && $condition[$k]!==""){
                if($k==="task_id"){
                    $match[$v] = new ObjectId($condition[$k]);
                }elseif($k==="status"){
                    $task_id = (new FollowtaskModel())->getKvData(['status' => (int)$condition[$k]]);
                    $task_ids = array_map(function ($v) { return new ObjectId($v); }, $task_id);
                    $match["task_id"] = ['$in' => $task_ids];
                }else{
                    $match[$v] = is_string($condition[$k])?trim($condition[$k]):(int)$condition[$k];
                }
            }
        }

        if(empty($match)){
            throw new FailedException('请至少传入一个条件作为查询');
        }
        
        $match['pushtime'] = ['$exists' => true];

        $pip = [['$project' => ['created_at' => ['$multiply' => ['$created_at', 1000]], 'task_id' => '$task_id', 'diagnosis' => '$diagnosis', 'user_id' => '$follow_staff.user_id', 'username' => '$follow_staff.username', 'department_id' => '$follow_staff.department_id', 'department_name' => '$follow_staff.department_name', 'followStatus' => '$followStatus', 'pushtime' => '$pushtime']], ['$project' => ['created_at' => ['$add' => [new UTCDateTime(0), '$created_at']], 'task_id' => '$task_id', 'diagnosis' => '$diagnosis', 'user_id' => '$user_id', 'username' => '$username', 'department_id' => '$department_id', 'department_name' => '$department_name', 'followStatus' => '$followStatus', 'pushtime' => '$pushtime']], ['$match' => $match], ['$lookup' => ['from' => 'follow_history', 'localField' => '_id', 'foreignField' => 'follow_id', 'as' => 'history']], ['$unwind' => ['path' => '$history', 'preserveNullAndEmptyArrays' => true]], ['$project' => ['_id' => false, 'department_id' => '$department_id', 'department_name' => '$department_name', 'diagnosis' => '$diagnosis', 'username' => '$username', 'pushtime' => '$history.pushtime', 'followStatus' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$followStatus', 1]]]], 'then' => '已完成', 'else' => '未完成']], 'smsStatus' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history.mode', 2]]]], 'then' => '已发送', 'else' => '']], 'mode' => '$history.mode', 'followResult' => '$history.resultName']]];

        $rets = ZhyxMongo::getInstance()->setCollection($this->name)->aggregate($pip);

        $arr = [];
        foreach ($rets as $k => $v) {
            $v_arr = (array)$v;
            $v_arr['wechat'] = '';
            $v_arr['pushtime']     = isset($v_arr['pushtime'])?$v_arr['pushtime']:"";
            $v_arr['followResult'] = isset($v_arr['followResult'])?$v_arr['followResult']:"";

            if (isset($v_arr['mode'])){
                switch($v_arr['mode']){
                    case 2: 
                        $v_arr['mode'] = '短信';
                        break;
                    case 3:
                        $v_arr['mode'] = 'APP/短信';
                        break;
                    case 4:  
                        $v_arr['mode'] = '电话';
                        break;  
                }
            }else{
                $v_arr['mode'] = "";
            }
            $arr[] = $v_arr;
        }
        return $arr;
    }

    /**
     * 统计个人报表
     * 
     * @param array $condition 查询条件
     * @return array
     */
    public function getFollowIndividualList(array $condition=[]): array
    {
        //$users = $this->getUserIds();
        
        $match = [];
        if (isset($condition["created_ymd"]) && !empty($condition["created_ymd"])){
            $start_time = new UtcDateTime(strtotime($condition['created_ymd'][0])*1000);
            $end_time   = new UtcDateTime(strtotime($condition['created_ymd'][1].' 23:59:59')*1000);
            $match["start_date"] = ['$gte' => $start_time,'$lte' => $end_time]; //拼接查询日期
        }

        $paramArr = ["staff_id" => "staff_id", "dept_id" => "dept_id", "task_id" => "task_id", "status" => "status"];
  
        foreach($paramArr as $k => $v){
            if(isset($condition[$k]) && $condition[$k]!==""){
                if($k==="task_id"){
                    $match[$v] = new ObjectId($condition[$k]);
                }elseif($k==="status"){
                    $task_id = (new FollowtaskModel())->getKvData(['status' => (int)$condition[$k]]);
                    $task_ids = array_map(function ($v) { return new ObjectId($v); }, $task_id);
                    $match["task_id"] = ['$in' => $task_ids];
                }else{
                    $match[$v] = is_string($condition[$k])?trim($condition[$k]):(int)$condition[$k];
                }
            }
        }

        if(empty($match)){
            throw new FailedException('请至少传入一个条件作为查询');
        }
        
//        if(!empty($users)){
//            $match['staff_id'] = ['$in' => $users];
//        }

        $pip = [['$match' => $match], ['$group' => ['_id' => ['year' => ['$year' => '$start_date'], 'month' => ['$month' => '$start_date']], 'task_num' => ['$sum' => '$task_num'], 'task_completed_number' => ['$sum' => '$task_completed_number'], 'phone_completed' => ['$sum' => '$phone_completed'], 'sms_completed' => ['$sum' => '$sms_completed'], 'phone_total' => ['$sum' => '$phone_total'], 'sms_total' => ['$sum' => '$sms_total']]], ['$project' => ['year' => '$_id.year', 'month' => '$_id.month', 'task_num' => '$task_num', 'task_completed_number' => '$task_completed_number', 'phone_completed' => '$phone_completed', 'sms_completed' => '$sms_completed', 'phone_total' => '$phone_total', 'sms_total' => '$sms_total']]];

        $rets = ZhyxMongo::getInstance()->setCollection("follow_report")->aggregate($pip);
        
        $arr = [];
        foreach ($rets as $k => $v) {
            unset($v['_id']);
            $v_arr = (array)$v;
            $v_arr['app_total'] = 0;
            $v_arr['app_completed'] = 0;
            $arr[] = $v_arr;
        }
        return $arr;
    }

    /**
     * 统计个人报表详情
     *
     * @param array $condition 查询条件
     * @return array
     */
    public function getFollowIndividualDetailedList(array $condition=[]): array
    {
        //$users = $this->getUserIds();

        $match = [];
        if (isset($condition["created_ymd"]) && !empty($condition["created_ymd"])){
            $start_time = new UtcDateTime(strtotime($condition['created_ymd'][0])*1000);
            $end_time   = new UtcDateTime(strtotime($condition['created_ymd'][1].' 23:59:59')*1000);
            $match["start_date"] = ['$gte' => $start_time,'$lte' => $end_time]; //拼接查询日期
        }

        $paramArr = ["staff_id" => "user_id", "dept_id" => "dept_id", "task_id" => "task_id", "status" => "status", "year" => "year", "month" => "month"];
  
        foreach($paramArr as $k => $v){
            if(isset($condition[$k]) && $condition[$k]!==""){
                if($k==="task_id"){
                    $match[$v] = new ObjectId($condition[$k]);
                }elseif($k==="status"){
                    $task_id = (new FollowtaskModel())->getKvData(['status' => (int)$condition[$k]]);
                    $task_ids = array_map(function ($v) { return new ObjectId($v); }, $task_id);

                    if (!empty($task_id)) {
                        $match["task_id"] = ['$in' => $task_ids];
                    }
                }else{
                    $match[$v] = is_string($condition[$k])?trim($condition[$k]):(int)$condition[$k];
                }
            }
        }

        if(empty($match)){
            throw new FailedException('请至少传入一个条件作为查询');
        }
        
//        if(!empty($users)){
//            $match['staff_id'] = ['$in' => $users];
//        }
        $match['pushtime'] = ['$exists' => true];

        $pip = [['$project' => ['created_at' => ['$multiply' => ['$created_at', 1000]], 'task_id' => '$task_id', 'diagnosis' => '$diagnosis', 'user_id' => '$follow_staff.user_id', 'dept_id' => '$follow_staff.department_id', 'username' => '$follow_staff.username', 'followStatus' => '$followStatus', 'pushtime' => '$pushtime']], ['$project' => ['created_at' => ['$add' => [new UTCDateTime(0), '$created_at']], 'task_id' => '$task_id', 'diagnosis' => '$diagnosis', 'user_id' => '$user_id', 'username' => '$username', 'dept_id' => '$dept_id', 'followStatus' => '$followStatus', 'pushtime' => '$pushtime']], ['$project' => ['year' => ['$year' => '$created_at'], 'month' => ['$month' => '$created_at'], 'start_date' => '$created_at', 'task_id' => '$task_id', 'diagnosis' => '$diagnosis', 'user_id' => '$user_id', 'username' => '$username', 'dept_id' => '$dept_id', 'followStatus' => '$followStatus', 'pushtime' => '$pushtime']], ['$match' => $match], ['$lookup' => ['from' => 'follow_history', 'localField' => '_id', 'foreignField' => 'follow_id', 'as' => 'history']], ['$unwind' => ['path' => '$history', 'preserveNullAndEmptyArrays' => true]], ['$project' => ['_id' => false, 'year' => '$year', 'month' => '$month', 'start_date' => '$start_date', 'diagnosis' => '$diagnosis', 'username' => '$username', 'pushtime' => '$history.pushtime', 'followStatus' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$followStatus', 1]]]], 'then' => '已完成', 'else' => '未完成']], 'smsStatus' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history.mode', 2]]]], 'then' => '已发送', 'else' => '']], 'mode' => '$history.mode', 'followResult' => '$history.resultName']]];

        $rets = ZhyxMongo::getInstance()->setCollection($this->name)->aggregate($pip);

        $arr = [];
        foreach ($rets as $k => $v) {
            $v_arr = (array)$v;
            $v_arr['wechat'] = '';
            $v_arr['pushtime']     = isset($v_arr['pushtime'])?$v_arr['pushtime']:"";
            $v_arr['followResult'] = isset($v_arr['followResult'])?$v_arr['followResult']:"";

            if (isset($v_arr['mode'])){
                switch($v_arr['mode']){
                    case 2: 
                        $v_arr['mode'] = '短信';
                        break;
                    case 3:
                        $v_arr['mode'] = 'APP/短信';
                        break;
                    case 4:  
                        $v_arr['mode'] = '电话';
                        break;  
                }
            }else{
                $v_arr['mode'] = "";
            }
            $arr[] = $v_arr;
        }
        return $arr;
    }

    /**
     * 获取任务详情统计
     *
     * @param string $task_id
     * @return array
     */
    public function getTaskDetailsStatistics(string $task_id): array
    {
        $pip = [['$match' => ['task_id' => new ObjectId($task_id)]], ['$lookup' => ['from' => 'followtask', 'localField' => 'task_id', 'foreignField' => '_id', 'as' => 'task_result']], ['$unwind' => ['path' => '$task_result', 'preserveNullAndEmptyArrays' => true]], ['$group' => ['_id' => ['task_id' => '$task_id', 'follow_staff' => '$follow_staff.user_id'], 'task_name' => ['$first' => '$taskname'], 'task_num' => ['$first' => '$task_result.patient_num'], 'follow_staff' => ['$first' => '$follow_staff.username'], 'task_id' => ['$first' => '$task_id'], 'task_done_num' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$followStatus', 1]]]], 'then' => 1, 'else' => 0]]], 'task_nodone_num' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$followStatus', 0]]]], 'then' => 1, 'else' => 0]]],'staff_task_num' => ['$sum' => 1], 'effective' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$is_effective', 1]],['$eq' => ['$followStatus', 1]]]], 'then' => 1, 'else' => 0]]], 'no_effective' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$is_effective', 0]]]], 'then' => 1, 'else' => 0]]]]], ['$group' => ['_id' => '$task_id', 'task_id' => ['$first' => '$task_id'], 'task_name' => ['$first' => '$task_name'], 'task_number' => ['$first' => '$task_num'], 'task_all_done_count' => ['$sum' => '$task_done_num'], 'task_all_nodone_count' => ['$sum' => '$task_nodone_num'], 'follow_staff' => ['$addToSet' => ['follow_staff' => '$follow_staff', 'staff_task_num' => '$staff_task_num', 'task_done_num' => '$task_done_num']], 'valid' => ['$sum' => '$effective'], 'invalid' => ['$sum' => '$no_effective'], 'noresults' => ['$sum' => '$task_nodone_num']]]];

        $data = ZhyxMongo::getInstance()->setCollection($this->name)->aggregate($pip);
        
        $ret = [];
        foreach ($data as $k => $v) {
            unset($v['_id']);
            unset($v['task_id']);
            $ret = (array)$v;
        }
        return $ret;
    }

    /**
     * 获取任务详情图形统计
     *
     * @param string $task_id
     * @return array
     */
    public function getTaskDetailsChartStatistics(string $task_id): array
    {
        $pip = [['$match' => ['task_id' => new ObjectId($task_id)]], ['$lookup' => ['from' => 'follow_history', 'localField' => '_id', 'foreignField' => 'follow_id', 'as' => 'history_result']], ['$unwind' => ['path' => '$history_result', 'preserveNullAndEmptyArrays' => true]], ['$group' => ['_id' => ['task_id' => '$task_id'], 'sms_num' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.mode', 2]]]], 'then' => 1, 'else' => 0]]], 'phone_num' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.mode', 4]]]], 'then' => 1, 'else' => 0]]], 'sms_done_num' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.mode', 2]]]], 'then' => 1, 'else' => 0]]], 'sms_reply_num' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.mode', 2]], ['$ne' => ['$history_result.status', 0]]]], 'then' => 1, 'else' => 0]]], 'sms_noreply_num' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.mode', 2]], ['$eq' => ['$history_result.status', 0]]]], 'then' => 1, 'else' => 0]]], 'phone_effective' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.mode', 4]], ['$eq' => ['$history_result.resultIsEffective', 1]]]], 'then' => 1, 'else' => 0]]], 'phone_no_effective' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.mode', 4]], ['$eq' => ['$history_result.resultIsEffective', 0]]]], 'then' => 1, 'else' => 0]]], 'patient_results_num' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.mode', 4]], ['$eq' => ['$history_result.resultCategory', 0]]]], 'then' => 1, 'else' => 0]]], 'phone_results_num' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.mode', 4]], ['$eq' => ['$history_result.resultCategory', 1]]]], 'then' => 1, 'else' => 0]]], 'phone_ff_number' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.result', 6]]]], 'then' => 1, 'else' => 0]]], 'phone_gj_number' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.result', 13]]]], 'then' => 1, 'else' => 0]]], 'phone_hmcw_number' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.result', 16]]]], 'then' => 1, 'else' => 0]]], 'phone_hmwx_number' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.result', 9]]]], 'then' => 1, 'else' => 0]]], 'phone_jjsf_number' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.result', 8]]]], 'then' => 1, 'else' => 0]]], 'phone_jsjt_number' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.result', 18]]]], 'then' => 1, 'else' => 0]]], 'phone_kh_number' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.result', 10]]]], 'then' => 1, 'else' => 0]]], 'phone_mzsc_number' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.result', 25]]]], 'then' => 1, 'else' => 0]]], 'phone_qtqk_number' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.result', 11]]]], 'then' => 1, 'else' => 0]]], 'phone_sw_number' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.result', 19]]]], 'then' => 1, 'else' => 0]]], 'phone_tj_number' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.result', 14]]]], 'then' => 1, 'else' => 0]]], 'phone_wd_number' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.result', 28]]]], 'then' => 1, 'else' => 0]]], 'phone_wfjt_number' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.result', 15]]]], 'then' => 1, 'else' => 0]]], 'phone_wrjt_number' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.result', 17]]]], 'then' => 1, 'else' => 0]]], 'phone_zdjj_number' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.result', 12]]]], 'then' => 1, 'else' => 0]]], 'phone_zy_number' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.result', 22]]]], 'then' => 1, 'else' => 0]]], 'phone_zysc_number' => ['$sum' => ['$cond' => ['if' => ['$and' => [['$eq' => ['$history_result.result', 24]]]], 'then' => 1, 'else' => 0]]]]], ['$project' => ['_id' => false, 'sms_num' => '$sms_num', 'phone_num' => '$phone_num', 'sms_done_num' => '$sms_done_num', 'sms_reply_num' => '$sms_reply_num', 'sms_noreply_num' => '$sms_noreply_num', 'phone_effective' => '$phone_effective', 'phone_no_effective' => '$phone_no_effective', 'patient_results_num' => '$patient_results_num', 'phone_results_num' => '$phone_results_num', 'patient_result' => ['phone_ff_number' => '$phone_ff_number', 'phone_mzsc_number' => '$phone_mzsc_number', 'phone_qtqk_number' => '$phone_qtqk_number', 'phone_sw_number' => '$phone_sw_number', 'phone_wd_number' => '$phone_wd_number', 'phone_zy_number' => '$phone_zy_number', 'phone_zysc_number' => '$phone_zysc_number'], 'phone_result' => ['phone_gj_number' => '$phone_gj_number', 'phone_hmcw_number' => '$phone_hmcw_number', 'phone_hmwx_number' => '$phone_hmwx_number', 'phone_jjsf_number' => '$phone_jjsf_number', 'phone_jsjt_number' => '$phone_jsjt_number', 'phone_kh_number' => '$phone_kh_number', 'phone_tj_number' => '$phone_tj_number', 'phone_wfjt_number' => '$phone_wfjt_number', 'phone_zdjj_number' => '$phone_zdjj_number', 'phone_wrjt_number' => '$phone_wrjt_number']]]];

        $data = ZhyxMongo::getInstance()->setCollection($this->name)->aggregate($pip);
        
        $ret = [];
        foreach ($data as $k => $v) {
            $ret = (array)$v;
        }
        return $ret;
    }

    /**
     * 获取键值数据
     *
     * @param array $where 条件
     * @param string $field 字段
     * @return array
     */
    public function getKvData(array $where, string $field): array
    {
        return  $this->where($where)->column($field);
    }

    /**
     * mongodb聚合查询
     * @param array $pip 条件
     * @return array
     */
    public function mongoAggregate(array $pip=[]): array
    {
        $data = ZhyxMongo::getInstance()->setCollection($this->name)->aggregate($pip);
        $ret = [];
        foreach ($data as $k => $v) {
            $ret[] = $v;
        }
        return $ret;
    }
}
